package com.haojiang.mh.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import com.haojiang.mh.R;
import com.haojiang.mh.utils.SizeUtil;

/**
 * 自定义带文本ProgressBar
 * <p>
 * Created by ZapFive on 2019-05-26.
 * <p>
 * wuzhuang@mirahome.me
 */
public class TextProgressBarView extends View {

    public static final int RIGHT = 0;
    public static final int TOP = 1;
    private int barColor, secBarColor, textColor;//进度条颜色、二级进度条颜色、文本颜色
    private int barWidth, secBarWidth;//进度条宽度、二级进度条宽度
    private Paint barPaint;
    private TextPaint textPaint;
    private float textWidth, textHeight, padding;
    private int width, height, defaultWidth, defaultHeight;
    private int maxValue, currValue, textType;//最大值、当前值、文字布局类型
    private RectF rectF = new RectF();

    public TextProgressBarView(Context context) {
        this(context, null);
    }

    public TextProgressBarView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TextProgressBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextProgressBarView, defStyleAttr, 0);
        barColor = a.getColor(R.styleable.TextProgressBarView_tpv_bar_color, 0xFF7D55FF);
        textColor = a.getColor(R.styleable.TextProgressBarView_tpv_text_color, 0xFFFFFFFF);
        barWidth = a.getDimensionPixelSize(R.styleable.TextProgressBarView_tpv_bar_width, SizeUtil.dp2px(context, 5));
        maxValue = a.getInt(R.styleable.TextProgressBarView_tpv_max_value, 100);
        currValue = a.getInt(R.styleable.TextProgressBarView_tpv_curr_value, 0);
        textType = a.getInt(R.styleable.TextProgressBarView_tpv_text_type, RIGHT);
        a.recycle();

        padding = SizeUtil.dp2px(context, 1);
        defaultWidth = SizeUtil.dp2px(context, 300);
        if (textType == RIGHT) {
            secBarColor = getResources().getColor(R.color.white_third);
            secBarWidth = SizeUtil.dp2px(context, 1);
            textHeight = SizeUtil.dp2px(context, 20);
            textWidth = SizeUtil.dp2px(context, 40);
            defaultHeight = (int) (padding * 2 + textHeight);
        } else if (textType == TOP) {
            secBarColor = 0xFFDEDEDE;
            secBarWidth = barWidth;
            textHeight = SizeUtil.dp2px(context, 30);
            textWidth = SizeUtil.dp2px(context, 35);
            defaultHeight = (int) (padding + barWidth + textHeight);
        }

        barPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        barPaint.setStyle(Paint.Style.FILL);

        textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setColor(textColor);
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setTextSize(SizeUtil.sp2px(context, 14));
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (textType == RIGHT) {
            barPaint.setColor(secBarColor);
            barPaint.setStrokeWidth(secBarWidth);
            canvas.drawLine(padding, height * 0.5f, width - padding - textWidth, height * 0.5f, barPaint);

            barPaint.setColor(barColor);
            barPaint.setStrokeWidth(barWidth);
            rectF.set(padding,
                    height * 0.5f - barWidth * 0.5f,
                    padding + (width - padding * 2 - textWidth) * currValue / maxValue,
                    height * 0.5f + barWidth * 0.5f);
            canvas.drawRoundRect(rectF, barWidth * 0.5f, barWidth * 0.5f, barPaint);

            canvas.drawText(
                    Math.round(((float) currValue * 100 / maxValue)) + "%",
                    width - textWidth * 0.5f,
                    SizeUtil.getBaseLine(textPaint, height * 0.5f + textHeight * 0.5f, textHeight),
                    textPaint
            );
        } else if (textType == TOP) {
            barPaint.setColor(secBarColor);
            barPaint.setStrokeWidth(secBarWidth);
            rectF.set(
                    padding,
                    height - padding - barWidth,
                    width - padding,
                    height - padding
            );
            canvas.drawRoundRect(rectF, secBarWidth * 0.5f, secBarWidth * 0.5f, barPaint);

            barPaint.setColor(barColor);
            barPaint.setStrokeWidth(barWidth);
            rectF.set(
                    padding,
                    height - padding - barWidth,
                    padding + (width - padding * 2) * currValue / maxValue,
                    height - padding
            );
            canvas.drawRoundRect(rectF, barWidth * 0.5f, barWidth * 0.5f, barPaint);

            canvas.drawText(
                    Math.round(((float) currValue * 100 / maxValue)) + "%",
                    width - textWidth * 0.5f,
                    SizeUtil.getBaseLine(textPaint, textHeight, textHeight),
                    textPaint
            );
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(
                getMeasuredLength(widthMeasureSpec, true),
                getMeasuredLength(heightMeasureSpec, false)
        );
    }

    private int getMeasuredLength(int length, boolean isWidth) {
        int specMode = MeasureSpec.getMode(length);
        int specSize = MeasureSpec.getSize(length);
        int size;
        int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();
        if (specMode == MeasureSpec.EXACTLY) {
            size = specSize;
        } else if (specMode == MeasureSpec.UNSPECIFIED) {
            size = isWidth ? defaultWidth : defaultHeight;
        } else {
            size = isWidth ? padding + defaultWidth : padding + defaultHeight;
            if (specMode == MeasureSpec.AT_MOST) {
                size = Math.min(size, specSize);
            }
        }
        return size;
    }

    public void setValue(int value) {
        this.currValue = value;
        if (currValue < 0) currValue = 0;
        else if (currValue > maxValue) currValue = maxValue;
        postInvalidate();
    }

    public void setMaxValue(int value) {
        this.maxValue = value;
        invalidate();
    }
}
